纤程 (Fiber)

1. 纤程简介

纤程(Fiber)是 Ruby 中的一种轻量级并发控制机制,类似于线程,但更加轻量级。纤程允许你在程序中创建可暂停和恢复的执行单元,而不需要操作系统级别的线程切换。纤程非常适合用于实现协作式多任务处理,尤其是在需要细粒度控制任务执行顺序的场景中。

1.1 纤程与线程的区别

  • 线程:由操作系统管理,可以并行执行,但需要处理复杂的同步问题。
  • 纤程:由程序员控制,不能并行执行,但可以更细粒度地控制任务的执行顺序。

2. 纤程的基本用法

2.1 创建纤程

要创建一个纤程,可以使用 Fiber.new 方法,并传入一个块作为纤程的执行体。

fiber = Fiber.new do
  puts "Fiber started"
  Fiber.yield # 暂停纤程
  puts "Fiber resumed"
end

2.2 启动纤程

使用 Fiber#resume 方法来启动纤程。纤程会在遇到 Fiber.yield 时暂停,并在下一次调用 resume 时恢复执行。

fiber.resume # 输出 "Fiber started"
fiber.resume # 输出 "Fiber resumed"

2.3 纤程的暂停和恢复

纤程可以通过 Fiber.yield 方法暂停,并通过 Fiber#resume 方法恢复。Fiber.yield 可以返回一个值给调用者,而 Fiber#resume 也可以传递参数给纤程。

fiber = Fiber.new do
  value = Fiber.yield("Hello") # 暂停纤程并返回 "Hello"
  puts "Received: #{value}"
end

puts fiber.resume # 输出 "Hello"
fiber.resume("World") # 输出 "Received: World"

3. 纤程的应用场景

3.1 协作式多任务处理

纤程非常适合用于协作式多任务处理,例如在网络服务器中处理多个客户端请求时,可以使用纤程来避免阻塞。

def handle_client(client)
  Fiber.new do
    while line = client.gets
      client.puts "Echo: #{line}"
    end
  end.resume
end

3.2 生成器

纤程可以用于实现生成器,生成一系列的值。

def fibonacci_generator
  Fiber.new do
    a, b = 0, 1
    loop do
      Fiber.yield(a)
      a, b = b, a + b
    end
  end
end

generator = fibonacci_generator
10.times { puts generator.resume }

4. 实践练习

4.1 实现一个简单的任务调度器

使用纤程实现一个简单的任务调度器,可以调度多个任务并按顺序执行。

class TaskScheduler
  def initialize
    @tasks = []
  end

  def add_task(&block)
    @tasks << Fiber.new(&block)
  end

  def run
    @tasks.each do |task|
      task.resume
    end
  end
end

scheduler = TaskScheduler.new

scheduler.add_task do
  puts "Task 1 started"
  Fiber.yield
  puts "Task 1 resumed"
end

scheduler.add_task do
  puts "Task 2 started"
  Fiber.yield
  puts "Task 2 resumed"
end

scheduler.run

4.2 实现一个简单的协程池

使用纤程实现一个简单的协程池,可以并发执行多个任务。

class CoroutinePool
  def initialize(size)
    @size = size
    @fibers = []
  end

  def submit(&block)
    @fibers << Fiber.new(&block)
  end

  def run
    until @fibers.empty?
      @fibers.each do |fiber|
        fiber.resume
      end
      @fibers.reject! { |fiber| fiber.alive? }
    end
  end
end

pool = CoroutinePool.new(2)

pool.submit do
  puts "Task 1 started"
  Fiber.yield
  puts "Task 1 resumed"
end

pool.submit do
  puts "Task 2 started"
  Fiber.yield
  puts "Task 2 resumed"
end

pool.run

5. 总结

纤程是 Ruby 中一种强大的并发控制机制,适合用于协作式多任务处理和生成器等场景。通过纤程,你可以更细粒度地控制任务的执行顺序,避免复杂的同步问题。希望本教程能帮助你更好地理解和使用纤程。

6. 进一步学习

  • 深入了解 Ruby 的并发模型,包括线程、纤程和事件驱动编程。
  • 探索其他语言中的类似机制,如 Python 的 yield 和 Go 的 goroutine。
  • 阅读 Ruby 官方文档中关于纤程的部分,了解更多高级用法和技巧。

通过本教程,你应该已经掌握了纤程的基本概念和用法,并能够将其应用于实际项目中。继续探索和实践,你将能够更深入地理解和掌握这一强大的工具。